package com.nowcoder.community.controller;

import com.nowcoder.community.annotation.LoginRequired;
import com.nowcoder.community.entity.Comment;
import com.nowcoder.community.entity.DiscussPost;
import com.nowcoder.community.entity.Page;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.service.*;
import com.nowcoder.community.util.CommunityConstant;
import com.nowcoder.community.util.CommunityUtil;
import com.nowcoder.community.util.HostHolder;
import com.qiniu.util.Auth;
import org.apache.commons.lang3.StringUtils;
import com.qiniu.util.StringMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>Title: UserController</p>
 * <p>author 12427</p>
 *
 * @version ver1.0
 * @date 2022/8/15 18:03
 */
@Controller
@RequestMapping("/user")
public class UserController implements CommunityConstant{

    private  static final Logger logger = LoggerFactory.getLogger(UserController.class);

    @Value("${community.path.upload}")
    private String uploadPath;
    @Value("${community.path.domain}")
    private String domain;
    @Value("${server.servlet.context-path}")
    private String contextPath;


    @Autowired
    private UserService userService ;

    @Autowired
    private HostHolder hostHolder ;

    @Autowired
    private LikeService likeService;

    @Autowired
    private FollowService followService ;

    @Autowired
    private DiscussPostService discussPostService ;

    @Autowired
    private CommentService commentService ;

    @Value("${qiniu.key.access}")
    private String accessKey ;

    @Value("${qiniu.key.secret}")
    private String secretKey ;

    @Value("${qiniu.bucket.header.name}")
    private String headerBucketName ;

    @Value("${qiniu.bucket.header.url}")
    private String headerBucketUrl ;



    @LoginRequired
    @RequestMapping(path = "/setting" , method = RequestMethod.GET)
    public String getSettingPage(Model model){

        // 上传文件的名称
        String fileName= CommunityUtil.generateUUID() ;

        // 设置响应的信息  七牛云自己的规定
        StringMap policy = new StringMap() ;
        policy.put("returnBody" , CommunityUtil.getJSONString(0)); // 希望成功的时候返回一个code:0
        // 生成上传凭证
        Auth auth = Auth.create(accessKey,secretKey);
        String uploadToken = auth.uploadToken(headerBucketName , fileName , 3600 , policy) ;

        model.addAttribute("uploadToken"  ,uploadToken) ;
        model.addAttribute("fileName" , fileName) ;


        return "/site/setting" ;
    }

    // 更新头像路径
    @RequestMapping(path = "/header/url" , method = RequestMethod.POST)
    @ResponseBody
    public String updateHeaderUrl(String fileName){
        if(StringUtils.isBlank(fileName)){
            return CommunityUtil.getJSONString(1 , "文件名不能为空" ) ;
        }
        String url = headerBucketUrl + "/" + fileName ;
        userService.updateHeader(hostHolder.getUser().getId() , url) ;

        return CommunityUtil.getJSONString(0) ;
    }


    // 废弃
    @Deprecated
    @LoginRequired
    @RequestMapping(path = "/upload" , method = RequestMethod.POST)
    public String uploadHeader(MultipartFile headerImage, Model model){
        if(headerImage == null) {
            model.addAttribute("error" , "您还没有选择图片") ;
            return "/site/setting" ;
        }
        // 读取文件的后缀
        String fileName = headerImage.getOriginalFilename();
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        if(StringUtils.isBlank(suffix)){
            model.addAttribute("error" , "文件格式不正确") ;
            return "/site/setting" ;
        }

        // 生成随机的文件名
        fileName = CommunityUtil.generateUUID() + suffix ;
        // 确定文件存放的路径
        File dest = new File(uploadPath + "/" + fileName) ;

        //  写进dest
        try {
            // 存储文件
            headerImage.transferTo(dest);
        } catch (IOException e) {
            logger.error("上传文件失败" + e.getMessage());
            throw  new RuntimeException("上传文件失败，服务器发生异常" , e ) ;
        }

        // 更新当前用户头像的路径（web路径）
        // http://localhost:8080/community/user/header/xxx.png
        // 通过HostHolder获取到当前用户
        User user = hostHolder.getUser() ;
        String headerUrl =  domain + contextPath + "/user/header/" + fileName ;
        userService.updateHeader(user.getId(),headerUrl) ;

        return "redirect:/index" ;
    }

    // 废弃
    @Deprecated
    @RequestMapping(path = "/header/{fileName}"  ,method = RequestMethod.GET)
    public  void getHeader(@PathVariable("fileName")  String fileName , HttpServletResponse response){
        // 服务器存放路径
        fileName = uploadPath + "/" + fileName ;

        // 解析文件后缀
        String suffix = fileName.substring(fileName.lastIndexOf(".")) ;

        // 响应图片
        response.setContentType("image/" + suffix);

        try (
                // 得到输出流 , 输出流不需要我们处理，这是Spring MVC 管理
                FileInputStream fis = new FileInputStream(fileName);
                // 创建文件的输入流 ， 需要我们手动关闭
                OutputStream os = response.getOutputStream();
        ){

            byte[] buffer = new byte[1024] ;
            int b = 0 ;
            while ((b = fis.read(buffer)) != -1) {
                os.write(buffer , 0 , b) ;
            }

        } catch (IOException e) {
            logger.error("读取头像失败" + e.getMessage());
        }

    }



    @RequestMapping(path="/updatePassword" , method = RequestMethod.POST)
    public String updatePassword(String oldPassword , String newPassword , Model model) {
        User user = hostHolder.getUser() ;
        Map<String, Object> map = userService.updatePassword(user.getId(), oldPassword, newPassword
        );

        if(map == null || map.isEmpty()) {
            //  map 是空的说明修改成功~
            return "redirect:/logout" ;
        }else {
            model.addAttribute("oldPasswordMsg" , map.get("oldPasswordMsg") );
            model.addAttribute("newPasswordMsg" , map.get("newPasswordMsg") );
            return "/site/setting" ;
        }
    }


    // 个人主页
    @RequestMapping(path = "/profile/{userId}" , method = RequestMethod.GET)
    public String getProfilePage(@PathVariable("userId") int userId , Model model){
        User user = userService.findUserById(userId) ;
        if(user == null ){
            throw new RuntimeException("该用户不存在") ;
        }

        // 用户基本信息封存
        model.addAttribute("user" , user) ;
        // 点赞的数量
        int likeCount = likeService.findUserLikeCount(userId);
        model.addAttribute("likeCount" , likeCount) ;


        // 关注数量

        long followeeCount = followService.findFolloweeCount(userId, CommunityConstant.ENTITY_TYPE_USER);
        model.addAttribute("followeeCount" ,followeeCount ) ;
        // 粉丝数量
        long followerCount = followService.findFollowerCount(ENTITY_TYPE_USER , userId) ;
        model.addAttribute("followerCount"  ,followerCount) ;

        // 是否已关注
        boolean hasFollowed = false ;

        if(hostHolder.getUser() != null ){
            hasFollowed = followService.hasFollowed(hostHolder.getUser().getId(), ENTITY_TYPE_USER, userId);
        }
        model.addAttribute("hasFollowed" , hasFollowed) ;


        return "/site/profile" ;
    }

    // 我的帖子
    @RequestMapping(path = "/mypost/{userId}" , method = RequestMethod.GET)
    public String getMyPost(@PathVariable("userId") int userId , Page page , Model model){
        User user = userService.findUserById(userId) ;
        if(user == null){
            throw new RuntimeException("该用户不存在!") ;
        }
        model.addAttribute("user" , user) ;

        // 分页信息
        page.setPath("/user/mypost/" + userId);
        page.setRows(discussPostService.findDiscussPostRows(userId));

        // 帖子列表
        List<DiscussPost> discussList = discussPostService
                .findDiscussPosts(userId , page.getOffset() , page.getLimit() , 0 );
        List<Map<String,Object>> discussVOList = new ArrayList<>();
        if(discussList!=null){
            for(DiscussPost post : discussList){
                Map<String,Object> map = new HashMap<>() ;
                map.put("discussPost" , post) ;
                map.put("likeCount" , likeService.findEntityLikeCount(ENTITY_TYPE_POST , post.getId())) ;
                discussVOList.add(map) ;
            }
        }

        model.addAttribute("discussPosts" , discussVOList) ;
        return "/site/my-post" ;
    }

    // 我的回复
    @RequestMapping(path = "/myreply/{userId}"  ,method = RequestMethod.GET)
    public String getMyReply(@PathVariable("userId") int userId ,
                             Page page , Model model){

        User user = userService.findUserById(userId) ;

        if(user == null) {
            throw new RuntimeException("该用户不存在!") ;
        }

        model.addAttribute("user" , user) ;


        // 分页信息
        page.setPath("/user/myreply/" + userId);
        page.setRows(commentService.findUserCount(userId));

        // 回复列表
        List<Comment> commentList = commentService.findUserComments(userId , page.getOffset() , page.getLimit()) ;
        List<Map<String , Object>> commentVOList = new ArrayList<>() ;
        if(commentList != null){
            for (Comment comment : commentList){
                Map<String , Object> map= new HashMap<>() ;
                map.put("comment" , comment ) ;
                DiscussPost post = discussPostService.findDiscussPostById(comment.getEntityId()
                );
                map.put("discussPost" , post) ;
                commentVOList.add(map) ;
            }
            model.addAttribute("comments" , commentVOList) ;
        }
        return "/site/my-reply" ;
    }


}
